import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import '../../config/public_color.dart';
import '../../config/public_text.dart';
import '../container/circle_container.dart';

/// FileName public_text_field
///
/// @Author lax
/// @Date 2023/7/4
///
/// @Description

class PublicTextField extends StatefulWidget {
  static TextStyle? defaultStyle;

  static TextStyle? defaultUnableStyle;

  static TextStyle? defaultHintTextStyle;

  static EdgeInsets? defaultPadding =
      const EdgeInsets.symmetric(horizontal: 12, vertical: 16);

  final String? text;

  late final String? hintText;

  final bool enable;

  final ValueChanged<String>? onChanged;

  late final TextStyle? style;
  late final TextStyle? unableStyle;
  late final TextStyle? hintStyle;
  final TextStyle? counterStyle;

  late final EdgeInsets? padding;

  final TextAlign? textAlign;
  final TextInputType? keyboardType;
  final List<TextInputFormatter>? inputFormatters;
  final InputDecoration? decoration;

  final int? maxLines;
  final int? minLines;
  final int? maxLength;

  final bool? obscureText;
  final bool? autofocus;
  final bool? unableShowHintText;
  final bool? showClearButton;

  final FocusNode? focusNode;
  final VoidCallback? onEditingComplete;
  final TextInputAction? textInputAction;

  PublicTextField({
    super.key,
    this.text,
    String? hintText,
    this.enable = true,
    this.onChanged,
    TextStyle? style,
    TextStyle? unableStyle,
    TextStyle? hintStyle,
    this.counterStyle,
    EdgeInsets? padding,
    this.textAlign,
    this.keyboardType,
    this.inputFormatters,
    this.decoration,
    this.maxLines = 1,
    this.minLines,
    this.maxLength,
    this.obscureText = false,
    this.autofocus = false,
    this.unableShowHintText = false,
    this.showClearButton = true,
    this.focusNode,
    this.onEditingComplete,
    this.textInputAction,
  }) {
    this.hintText = hintText ?? PublicText.pleaseInput;
    this.style = style ??
        defaultStyle ??
        TextStyle(
            fontSize: 14,
            fontWeight: FontWeight.normal,
            color: PublicColor.darkText);
    this.unableStyle = unableStyle ??
        defaultUnableStyle ??
        TextStyle(
            fontSize: 14,
            fontWeight: FontWeight.normal,
            color: PublicColor.darkText);
    this.hintStyle = hintStyle ??
        defaultHintTextStyle ??
        TextStyle(
            fontSize: 14,
            fontWeight: FontWeight.normal,
            color: PublicColor.hintText);
    this.padding = padding ?? defaultPadding;
  }

  @override
  State<StatefulWidget> createState() {
    return _PublicTextFieldState();
  }
}

class _PublicTextFieldState extends State<PublicTextField> {
  late final TextEditingController controller;

  final FocusNode _focusNode = FocusNode();
  bool _hasFocus = false;

  void _handleFocusChange() {
    setState(() {
      _hasFocus = _focusNode.hasFocus;
    });
  }

  @override
  void initState() {
    super.initState();
    controller = TextEditingController(text: widget.text);
    _focusNode.addListener(_handleFocusChange);
  }

  @override
  void didUpdateWidget(covariant PublicTextField oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (controller.text != widget.text) {
      controller.value = TextEditingValue(
        text: widget.text ?? '',
        selection: TextSelection.collapsed(offset: (widget.text ?? '').length),
      );
    }
  }

  @override
  void dispose() {
    controller.dispose();
    _focusNode.removeListener(_handleFocusChange);
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          child: textField(),
        ),
        Visibility(
          visible: widget.focusNode == null &&
              _hasFocus &&
              widget.maxLines == 1 &&
              widget.showClearButton == true &&
              controller.text.isNotEmpty,
          replacement: SizedBox(width: widget.padding?.right),
          child: clearButton(),
        ),
      ],
    );
  }

  Widget textField() {
    return TextField(
      enabled: widget.enable,
      controller: controller,
      textAlign: widget.textAlign ?? TextAlign.start,
      onChanged: (value) {
        setState(() {
          widget.onChanged?.call(value);
        });
      },
      style: widget.enable ? widget.style : widget.unableStyle,
      inputFormatters: widget.inputFormatters,
      keyboardType: widget.keyboardType,
      maxLines: widget.maxLines,
      minLines: widget.minLines,
      maxLength: widget.maxLength,
      obscureText: widget.obscureText ?? false,
      autofocus: widget.autofocus ?? false,
      focusNode: widget.focusNode ?? _focusNode,
      onEditingComplete: widget.onEditingComplete,
      textInputAction: widget.textInputAction,
      decoration: widget.decoration ??
          InputDecoration(
            isCollapsed: true,
            hintText: (!widget.enable && widget.unableShowHintText != true)
                ? null
                : widget.hintText,
            hintStyle: widget.hintStyle,
            border: InputBorder.none,
            focusedBorder: InputBorder.none,
            contentPadding: widget.padding == null
                ? null
                : EdgeInsets.only(
                    left: widget.padding!.left,
                    top: widget.padding!.top,
                    bottom: widget.padding!.bottom),
            counterStyle: widget.counterStyle,
          ),
    );
  }

  Widget clearButton() {
    return InkWell(
      onTap: () {
        controller.clear();
        widget.onChanged?.call('');
        setState(() {});
      },
      child: Container(
        color: Colors.transparent,
        padding:
            EdgeInsets.only(left: 4, right: max(widget.padding?.right ?? 0, 8)),
        child: CircleContainer(
          color: widget.hintStyle?.color?.withOpacity(0.5),
          padding: const EdgeInsets.all(2),
          child: const Icon(Icons.clear, color: Colors.white, size: 12),
        ),
      ),
    );
  }
}
